const express = require('express');
const router = express.Router();
const { Article } = require('../../models');
const { Op, where } = require('sequelize');
const { NotFound } = require('http-errors');
const { success, failure } = require('../../utils/responses');
const { getKeysByPattern, delKey, getKey, setKey } = require('../../utils/redis');
/**
 * 白名单参数过滤
 * */
const filterBody = (data) => {
  return {
    title: data.title,
    content: data.content,
  };
};

/**
 * 公共方法: 查询当前文章
 * */

async function getArticle(req) {
  const { id } = req.params;
  let article = await getKey(`article:${id}`);
  if (!article) {
    article = await Article.findByPk(id);
    if (!article) {
      throw new NotFound(`ID: ${id}的文章为找到`);
    }
    await setKey(`article:${id}`, article);
  }
  return article;
}

/**
 * 查询文章列表
 * */
router.get('/', async function (req, res) {
  try {
    const query = req.query;
    // 当前第几页，如果不传默认第一页
    const currentPage = Math.abs(Number(query.currentPage)) || 1;
    // 当前多少条数据，如果不传默认10条数据
    const pageSize = Math.abs(Number(query.pageSize)) || 10;
    // 计算offset
    const offset = (currentPage - 1) * pageSize;

    const condition = {
      where: {},
      order: [['id', 'DESC']],
      limit: pageSize,
      offset,
    };
    const title = decodeURIComponent(query.title);
    if (title) {
      condition.where.title = {
        [Op.like]: `%${title}%`,
      };
    }
    // 查询呗软删除的数据
    if (query.deleted === 'true') {
      condition.paranoid = false;
      condition.where.deletedAt = {
        [Op.not]: null,
      };
    }

    const { count: total, rows } = await Article.findAndCountAll(condition);
    console.log(rows, 'condition');
    success(res, '查询成功', {
      articles: rows,
      pagination: {
        total,
        currentPage,
        pageSize,
      },
    });
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 查询文章详情
 * */
router.get('/:id', async function (req, res) {
  try {
    const articles = await getArticle(req);
    success(res, '查询成功', { articles });
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 创建文章
 * */
router.post('/', async function (req, res) {
  try {
    const body = filterBody(req.body);
    const articles = await Article.create(body);
    await clearCache();
    success(res, '创建成功', { articles }, 201);
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 删除文章
 * */
router.delete('/:id', async function (req, res) {
  try {
    const article = await getArticle(req);
    await article.destroy();
    await clearCache(article.id);
    success(res, '删除成功');
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 批量删除文章
 * */
router.post('/delete', async function (req, res) {
  try {
    const { id } = req.body;
    await Article.destroy({ where: { id } });
    await clearCache(id);
    success(res, '移动到回收站成功');
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 从回收站恢复数据
 *
 * post /admin/articles/restore
 * */
router.post('/restore', async function (req, res) {
  try {
    const { id } = req.body;
    await Article.restore({ where: { id } });
    success(res, '恢复数据成功');
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 彻底删除数据
 *
 * post /admin/articles/restore
 * */
router.post('/force_delete', async function (req, res) {
  try {
    const { id } = req.body;
    await Article.destroy({ where: { id }, force: true });
    await clearCache(id);
    success(res, '彻底删除成功');
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 更新文章
 * */
router.put('/:id', async function (req, res) {
  try {
    const article = await getArticle(req);
    const body = filterBody(req.body);
    const data = await article.update(body);
    await clearCache(article.id);
    success(res, '更新成功', data);
  } catch (error) {
    failure(res, error);
  }
});

/**
 * 清除缓存
 * @returns {Promise<void>}
 *
 */
async function clearCache(id = null) {
  const keys = await getKeysByPattern('articles:*');
  if (keys.length !== 0) {
    await delKey(keys);
  }
  if (id) {
    const keys = Array.isArray(id) ? id.map((item) => `article:${item}`) : `article:${id}`;
    await delKey(keys);
  }
}

module.exports = router;
